package com.starblink.web.core

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.webkit.WebSettings
import android.webkit.WebView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.starblink.android.basic.user.UserDataCenter.clearUserAgentData
import com.starblink.android.basic.user.UserDataCenter.getUserAgentData
import com.starblink.basic.log.SKLogger
import com.starblink.basic.util.CheckUtil
import com.starblink.basic.util.CommUtils
import com.starblink.web.BuildConfig
import com.starblink.android.basic.bridge.BridgeInvokeDispatcher
import com.starblink.web.util.WebCacheUtil
import com.starblink.web.util.WebUtil
import java.io.File

class GuangWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : WebView(context, attrs), LifecycleEventObserver {
    private val TAG="GuangWebView"

    private val mWebViewClient by lazy { BaseWebViewClient(settings) }
    private val mWebChromeClient by lazy { BaseWebChromeClient() }
    private var userAgentString:String //记录初始值
    private var jsInterface= GuangJSBridge(this)
    private var ifCacheWeb:Boolean=false //从webView Cache中获取到的
    private var ifGuangUrl:Boolean=false //是否是自己的H5
    private var webJsI: WebJsI?=null //交互接口
    init {
        // 白色背景
        setBackgroundColor(Color.TRANSPARENT)
        setBackgroundResource(com.starblink.basic.style.R.color.clr_f1f5f9)

        WebUtil.defaultSettings(settings)

        userAgentString=settings.userAgentString

        setLayerType(LAYER_TYPE_HARDWARE, null) //启动webView硬件加速
        isVerticalScrollBarEnabled = false
        isHorizontalScrollBarEnabled = false
        overScrollMode = OVER_SCROLL_NEVER

        webViewClient = mWebViewClient
        webChromeClient = mWebChromeClient

        //跨进程时使用
        BridgeInvokeDispatcher.getInstance().bindService()

        //设置js交互
        addJavascriptInterface(jsInterface,"WebViewJavascriptBridge")

        setWebContentsDebuggingEnabled(BuildConfig.DEBUG) //WebView开启可调式
    }

    //监听事件
    fun setOnWebChangeListener(listener: OnWebChangeListener) {
        mWebViewClient.mListener=listener
        mWebChromeClient.mListener=listener
    }

    //js 方法交互
    fun setWebJsI(webJsI: WebJsI?){
        this.webJsI=webJsI
        mWebChromeClient.setWebJsI(webJsI)
        jsInterface.setWebJsI(webJsI)
    }

    //通知回调H5方法
    fun onActivityResult(eventKey:String,result:String){
        jsInterface.onActivityResult(eventKey,result)
    }

    /**
     * 设置是否使用缓存
     * 默认使用缓存 只有自己的H5链接使用拦截缓存
     */
    private fun setUseCache(userCache:Boolean=true){
        var ifUseInterceptCache=userCache
        var ifUseWebCacheMode=userCache
        if(!ifGuangUrl){
            //不是自己的链接 不使用拦截资源缓存
            ifUseInterceptCache=false
        }
        settings.cacheMode=if(ifUseWebCacheMode) WebSettings.LOAD_DEFAULT else WebSettings.LOAD_NO_CACHE
        mWebViewClient.ifUseCache=ifUseInterceptCache
    }
    //更新userAgentString
    //会影响到 Boozt OOPS 真人识别时会循环识别
    //外链地址 不加UA
    //ifStrictMode 是否宽松模式 宽松模式加上UA
    private fun updateUserAgent(ifStrictMode:Boolean=false){
        if(ifGuangUrl||ifStrictMode) {
            clearUserAgentData()
            settings.userAgentString =
                getUserAgentData() + "##" + userAgentString
        }else{
            settings.userAgentString =userAgentString
        }
        SKLogger.d(TAG,"updateUserAgent --- ${settings.userAgentString}")
    }
    //设置是否预加载的webview
    fun setCacheWeb(ifCacheWeb:Boolean){
        this.ifCacheWeb=ifCacheWeb
    }

    //自定义加载链接方法
    fun guangLoadUrl(url: String,userCache:Boolean=true,ifStrictMode:Boolean=false) {
        SKLogger.d(TAG,"当前加载的H5地址 --- $url")
        if (CheckUtil.isEmpty(url)) {
            return
        }
        ifGuangUrl=WebUtil.isGuangUrl(url)
        setUseCache(userCache)
        updateUserAgent(ifStrictMode)
        if(ifCacheWeb){
            //命中预加载中的webview 不需要重新加载地址
            webJsI?.showLoadingAnim(!mWebChromeClient.ifLoadSuccess)
            return
        }

        //上次加载页面闪现问题处理 开启硬件加速后会好很多
        visibility= View.GONE //加载默认隐藏加载成功后展示
        CommUtils.getHandler()
            .postDelayed(
                {
                    visibility = View.VISIBLE
                    webJsI?.showLoadingAnim(!mWebChromeClient.ifLoadSuccess)//加载完成就不需要显示loading
                },
                200
            )//0.2秒后处理

        loadUrl(url)
    }

    override fun loadUrl(url: String) {
        super.loadUrl(url)
        //记录埋点的URL 包括重定向的URL在内
        mWebViewClient.putSpmLoadUrl(url)
    }

    //获取预加载的H5标题
    fun getPreWebTitle():String?{
        return mWebChromeClient.preWebTitle
    }

    override fun canGoBack(): Boolean {
        val backForwardList = copyBackForwardList()
        val currentIndex = backForwardList.currentIndex - 1
        if (currentIndex >= 0) {
            val item = backForwardList.getItemAtIndex(currentIndex)
            if (item?.url == "about:blank") {
                return false
            }
        }
        return super.canGoBack()
    }

    /**
    * 生命周期 onResume()
    */
    @SuppressLint("SetJavaScriptEnabled")
    override fun onResume() {
        super.onResume()
        settings.javaScriptEnabled = true
    }

    /**
     * 生命周期 onPause()
     */
    override fun onPause() {
        super.onPause()
    }

    /**
     * 生命周期 onDestroy()
     * 父类没有 需要自己写
     */
    fun onDestroy() {
        settings.javaScriptEnabled = false
        release()
    }


    //自定义destroy方法 主动触发销毁
    fun destroy(release:Boolean){
        if(release){
            super.destroy()
        }
    }
    /**
     * 重写destroy 否则webView缓存池会莫名被回收销毁
     */
    override fun destroy() {
        SKLogger.d(TAG,"---webView destroy被调用---")
    }

    //释放
    fun release(){
        setWebJsI(null)
        //被回收时 重置初始化参数
        mWebChromeClient.preWebTitle=null
        ifCacheWeb=false
        loadUrl("about:blank")
        mWebViewClient.clearSpmLoadUrl()
        (parent as ViewGroup?)?.removeView(this)
        removeAllViews()
    }

    //重写清理缓存方法
    override fun clearCache(includeDiskFiles: Boolean) {
        super.clearCache(includeDiskFiles)
        WebCacheUtil.clearPreWebView() //清理预加载页面
        if(includeDiskFiles){
            //清除磁盘缓存
            WebCacheUtil.clearCacheFolder(File(WebCacheUtil.getWebViewCachePath(context)))
        }
    }


    /**
     * 设置 WebView 生命管控（自动回调生命周期方法）
     */
    fun setLifecycleOwner(owner: LifecycleOwner) {
        owner.lifecycle.addObserver(this)
    }

    /**
     * 生命周期回调
     */
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_RESUME -> {
                SKLogger.d(TAG,"onStateChanged -> ON_RESUME")
                onResume()
            }
            Lifecycle.Event.ON_STOP -> {
                SKLogger.d(TAG,"onStateChanged -> ON_STOP")
                onPause()
            }
            Lifecycle.Event.ON_DESTROY -> {
                SKLogger.d(TAG,"onStateChanged -> ON_DESTROY")
                source.lifecycle.removeObserver(this)
                onDestroy()
            }
            else -> {}
        }
    }

    interface OnWebChangeListener {
        fun titleChange(title: String?)
        fun progressChange(progress: Int)
        fun onInnerLinkChecked()
        fun onWebLoadError()
        fun onWebLoadStart(url: String)
        fun onWebLoadFinish(url: String?)
        //H5加载状态监听 埋点使用 url code location
        fun onWebLoadStatus(params:Map<String,String>)
    }

    interface WebJsI{
        fun showTitleBar(show:Boolean?) //是否显示标题栏
        fun setStatusBarColor(dark:Boolean?) //设置状态栏主题
        fun appShare(urlLink:String?) //app分享
        fun updateStoreSubscribeState(storeId:String?,subOrNot:Int?) //店铺id数据刷新  subOrNot是否收藏
        fun showLoadingAnim(show:Boolean?) //是否展示loading
        fun tryBack()//web回退或退出web容器
        fun closeH5()//直接关闭web容器
        fun accWebPages(webPages:List<String>?)//预先加载H5列表
        fun toastAddWish(productId: String)//收藏成功后toast
        fun addCollectedProductToBoard(productId:String?,type:Int,mainImg:String?) //添加已收藏的商品到心愿单
        fun addVWishlistFail()//未登录状态收藏超过10时弹框
    }

}